//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#if _MSC_VER > 1000
#pragma once
#endif

#ifndef __CMODULE_H__
#define __CMODULE_H__

#include <elasys_server.h>
#include <linknode.h>
#include <objenum.h>

#define _MAX_MODULE_PATH 260

class CModule : public ObjectEnumeratorNode, public IModule
{
public:
    CARAPI_(IInterface *) GetObject() { return (IModule *)this; }

public:
    CARAPI_(PInterface) Probe(
        /* [in]  */ REIID riid);

    CARAPI_(UInt32) AddRef();

    CARAPI_(UInt32) Release();

    CARAPI Aggregate(
        /* [in] */ AggrType aggrType,
        /* [in] */ PInterface pObject);

    CARAPI GetDomain(
        /* [out] */ PInterface *ppObject);

    CARAPI GetBaseAddress(
        /* [out] */ Address * pBase);

    CARAPI GetEntryPointAddress(
        /* [out] */ Address * pEntryPoint);

    CARAPI GetMemorySize(
        /* [out] */ MemorySize * pSize);

    CARAPI GetName(
        /* [out] */ WStringBuf * name);

    CARAPI GetFullPath(
        /* [out] */ WStringBuf * name);

    CARAPI GetProcAddressByName(
        /* [in] */ AString Name,
        /* [out] */ Address * pAddress);

    CARAPI GetProcAddressByOrdinal(
        /* [in] */ Int32 ordinal,
        /* [out] */ Address * pAddress);

    CARAPI GetResourceSection(
        /* [out] */ Address * pAddress);

    CARAPI GetSectionByName(
        /* [in] */ AString Name,
        /* [out] */ Address * pAddress);

    CARAPI FindResource(
        /* [in] */ WString wsName,
        /* [in] */ WString wsType,
        /* [out] */ Address * pAddress,
        /* [out] */ MemorySize * pSize);

public:
    CModule(ProcessId processId, IProcess * pOwner, PVoid hLock)
            : m_processId(processId),
              m_pOwner(pOwner),
              m_hModuleListLock(hLock),
              m_hModule(NULL) {}

    virtual ~CModule();

    ECode Initialize(
        /* [in] */ WString name,
        /* [in] */ ModuleLoadFlags flags);

    ECode Initialize(
        /* [in] */ PVoid hModule);

    Boolean Compare(
        /* [in] */ WString name);

    Boolean Compare(
        /* [in] */ Address address);

private:
    ProcessId  m_processId;
    IProcess * m_pOwner;
    PVoid      m_hModuleListLock;
    PVoid      m_hModule;

    wchar_t    m_name[_MAX_MODULE_PATH];
    wchar_t    m_path[_MAX_MODULE_PATH];

    Address    m_baseAddr;
    Address    m_entryPoint;
    MemorySize m_sizeofImage;

private:
    Interlocked m_cRef;
};

INLINE Boolean CModule::Compare(WString name)
{
    return !name.Compare(m_name, StringCase_Insensitive);
}

INLINE Boolean CModule::Compare(Address address)
{
    return ((address >= m_baseAddr) && (address < m_baseAddr + m_sizeofImage));
}

#endif //__CMODULE_H_

